package com.yp.infrastructure.axon.interceptor.command;

import com.yp.infrastructure.axon.annotation.AggregateCommandHandlerInterceptor;
import com.yp.infrastructure.axon.interceptor.IAxonCommandHandlerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.axonframework.commandhandling.CommandMessage;
import org.axonframework.messaging.Message;
import org.axonframework.messaging.annotation.HandlerEnhancerDefinition;
import org.axonframework.messaging.annotation.MessageHandlingMember;
import org.axonframework.messaging.annotation.WrappedMessageHandlingMember;

import javax.annotation.Nonnull;
import javax.annotation.Resource;
import java.util.Map;

@Slf4j
public class MsgEnhancedHandlerDefinition implements HandlerEnhancerDefinition {


    @Override
    public <T> MessageHandlingMember<T> wrapHandler(MessageHandlingMember<T> original) {

        return original.annotationAttributes(AggregateCommandHandlerInterceptor.class)
                .map(attr -> (MessageHandlingMember<T>) new MethodCommandMessageHandlingMember<>(
                        original, attr))
                .orElse(original);
    }


    @Slf4j
    private static class MethodCommandMessageHandlingMember<T> extends WrappedMessageHandlingMember<T> {

        @Resource
        private IAxonCommandHandlerInterceptor interceptor;

        private MethodCommandMessageHandlingMember(MessageHandlingMember<T> delegate,
                                                   Map<String, Object> annotationAttributes) {
            super(delegate);
            log.debug("启动具有拦截Annotation标识的拦截器 {}", delegate.toString());
        }

        @Override
        public boolean canHandle(@Nonnull Message<?> message) {
            if (!TypeUtils.isInstance(message, CommandMessage.class)) return super.canHandle(message);
            CommandMessage<?> commandMessage = (CommandMessage<?>) message;
            String tmp = commandMessage.getCommandName();
            log.info("{}, {}", tmp, message.getIdentifier());
            if (interceptor.onCommandHandlerEnhancedDefinitionInterceptor(commandMessage))
                return super.canHandle(message);
            return false;
        }

    }
}
